package com.example.emb.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.example.emb.entity.Groupdtable;
import com.example.emb.entity.Grouptable;
import com.example.emb.entity.Stuworktable;
import com.example.emb.entity.Worktable;
import com.example.emb.entity.pjo.MiniWork;
import com.example.emb.mapper.GroupdtableMapper;
import com.example.emb.mapper.GrouptableMapper;
import com.example.emb.mapper.StuworktableMapper;
import com.example.emb.mapper.WorktableMapper;
import com.example.emb.service.StudentService;
import com.example.emb.service.common.MinioService;
import com.example.emb.service.exception.NoRightToAccessException;
import com.example.emb.service.exception.UnableToWriteException;
import com.example.emb.service.exception.upLoadFailedException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.simp.SimpMessagingTemplate;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

@Service
public class StudentServiceImpl implements StudentService {
    @Autowired
    GrouptableMapper grouptableMapper;
    @Autowired
    WorktableMapper worktableMapper;
    @Autowired
    StuworktableMapper stuworktableMapper;
    @Autowired
    GroupdtableMapper groupdtableMapper;

    @Autowired
    MinioService minioService;

//    public StudentServiceImpl(SimpMessagingTemplate messagingTemplate) {
//        this.messagingTemplate = messagingTemplate;
//    }

    //todo
    @Override
    public List<MiniWork> GetWorkList(int groupId) {
        Grouptable group=grouptableMapper.selectById(groupId);
        int classId=group.getClassId();
        QueryWrapper<Worktable> queryWrapper=new QueryWrapper<>();
        queryWrapper.eq("classId",classId);
        List<Worktable> list=worktableMapper.selectList(queryWrapper);
        List<MiniWork> list1=new ArrayList<>();
        for (Worktable item : list) {
            MiniWork work=new MiniWork();
            work.setWorkId(item.getId())
                    .setModifiedTime(item.getModifiedTime())
                    .setEndTime(item.getEndTime())
                    .setIsFinal(item.getIsFinal())
                    .setIsFinished(item.getIsFinished())
                            .setName(item.getWorkname())
                                    .setRate(item.getRepeatRate());
            //如果是已经完成了的，就查看是不是有显示出来的查重率
            QueryWrapper<Stuworktable>queryWrapperStu=new QueryWrapper<>();
            queryWrapperStu.eq("groupId",groupId)
                            .eq("workId",item.getId());
            Stuworktable stuworktable=stuworktableMapper.selectOne(queryWrapperStu);
            if(stuworktable!=null){
                work.setMyRate(stuworktable.getRepeatRate());
            }else {
                work.setMyRate(0.0);
            }
            // 对比是不是已经截至并且未提交
            Date date=new Date();
            if(item.getEndTime().compareTo(date)<0){
                work.setIsFinal(1);
                if(stuworktable==null)
                    work.setIsFinished(0);
                else
                    work.setIsFinished(1);
            }
            else {
                work.setIsFinal(0);
                work.setIsFinished(0);
            }
            list1.add(work);
        }

        return list1;
    }


    @Override
    public Stuworktable InitGroupWork(int GroupId, int WorkId) {
        Stuworktable stuworktable=new Stuworktable();
        Worktable worktable=worktableMapper.selectById(WorkId);
        Date date=new Date();
        java.sql.Date SqlDate=new  java.sql.Date(date.getTime());
        stuworktable.setGroupId(GroupId)
                .setWorkid(WorkId)
                .setWorkDoc(worktable.getModel())
                .setFinishTime(SqlDate);
        int stuWorkId=stuworktableMapper.insert(stuworktable);
        stuworktable.setId(stuWorkId);
        return stuworktable;
    }

    @Override
    public Boolean JudgeIsExist(int GroupId, int WorkId) {
        QueryWrapper<Stuworktable> queryWrapper=new QueryWrapper<>();
        queryWrapper.eq("GroupId",GroupId)
                .eq("workid",WorkId);
        if(stuworktableMapper.selectOne(queryWrapper)==null)
            return false;
        return true;
    }

    //申请一个读写锁来实现多人编辑受到的影响
    private final ReadWriteLock lock = new ReentrantReadWriteLock();
    @Override
    public Stuworktable UpdateGroupWork(Long stuId, int groupId, int workId, String Doc) {
        Stuworktable worktable=stuworktableMapper.selectById(workId);
        QueryWrapper<Groupdtable> queryWrapper=new QueryWrapper<>();
        queryWrapper.eq("Uid",stuId)
                .eq("GroupId",groupId);
        Groupdtable groupdtable=groupdtableMapper.selectById(queryWrapper);
        if(worktable.getGroupId()==groupId && groupdtable!=null){
            if(!lock.writeLock().tryLock()){
                throw new UnableToWriteException("你的队友正在编辑，请等待");
            }
            try {
                worktable.setWorkDoc(Doc);
                stuworktableMapper.updateById(worktable);
                //使用websocket
                notifyFileUpdate();
                return worktable;
            }finally {
                lock.writeLock().unlock();
            }
        }
        else
            throw new NoRightToAccessException("没有访问权限");
    }

    //引入实时通知的功能，实现编辑后读的人的界面同步变化
    private SimpMessagingTemplate messagingTemplate;

    public void FileService(SimpMessagingTemplate messagingTemplate) {
        this.messagingTemplate = messagingTemplate;
    }
    private void notifyFileUpdate() {
        messagingTemplate.convertAndSend("/topic/fileUpdate", "File has been updated"); // 发送消息给订阅者
    }
    @Override
    public String getWorkDoc(Long stuId, int GroupId, int workId) {
        //先判断是否有读取作业内容的权限
        Stuworktable worktable=stuworktableMapper.selectById(workId);
        QueryWrapper<Groupdtable> queryWrapper=new QueryWrapper<>();
        queryWrapper.eq("Uid",stuId)
                .eq("GroupId",GroupId);
        Groupdtable groupdtable=groupdtableMapper.selectById(queryWrapper);
        lock.readLock().lock();
        try {
            if(worktable.getGroupId()==GroupId && groupdtable!=null){
                return worktable.getWorkDoc();
            }
            else
                throw new NoRightToAccessException("没有访问权限");
        }finally {
            lock.readLock().unlock();
        }
    }

    @Override
    public Void upLoadFiles(MultipartFile file,int StuWorkId,String Type) throws Exception {
        //上传的话会把之前的给挤下去
        String result=minioService.uploadFile(file);
        Stuworktable stuworktable=new Stuworktable();
        stuworktable=stuworktableMapper.selectById(StuWorkId);
        if(result!="wrong"){
            if(Type.equals("zip")){
                if(stuworktable.getZip()!=null){
                    minioService.deleteFile(stuworktable.getZip());
                }
                stuworktable.setZip(result);
            }
            if(Type.equals("video")){
                if(stuworktable.getZip()!=null){
                    minioService.deleteFile(stuworktable.getVideo());
                }
                stuworktable.setVideo(result);
            }
            stuworktableMapper.updateById(stuworktable);
        }
        else
            throw new upLoadFailedException("文件上传失败，请重新上传");
        return null;
    }
}
